import java.io.BufferedReader;

import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;




public class MainThread extends Thread{
	Peer parent =null;
	
	public class FoundFile{
		
		public String name;
		public int size;
		public int no;
		
		public FoundFile(String n, int s){
			name = n;
			size = s;

		}
	}
	
	Map<String, FoundFile> files = new HashMap<String, FoundFile>();
	
	
	public MainThread(Peer parent)
	{
		this.parent=parent;
	}
	
	void searchOpt() throws IOException
	{
		System.out.println("Keywords: ");
		BufferedReader words = new BufferedReader(new InputStreamReader(System.in));
		String keyWords = "";
		
		keyWords = words.readLine();

		String searchToSend = QueryFactory.search(keyWords);
		
		String[] aux = searchToSend.split(" ");
		parent.setActiveSearchId(aux[1]);
		
		DatagramPacket sendSearch = new DatagramPacket(searchToSend.getBytes(), searchToSend.length(), parent.address, parent.controlport);
		parent.controlSocket.send(sendSearch);

	}
	
	public void run()
	{
		while(true){
			System.out.println("**** Menu ****\n1 - Search for file\n2 - Downloads status\n3 - Cancel download\n0 - Exit");
			
			BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in));
			String opt = "";
			try {
				opt = buffer.readLine();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			
			switch(opt){
			case "1":
				try {
					searchOpt();
					Thread.sleep(3000);
				} catch (IOException e) {
					e.printStackTrace();
					
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				if(showFiles())
					getChosenFile();
				
				break;
				
			case "2":
				downloadStatus();
				break;
				
			case "3":
				cancelDownload(); 
				break;
	
				
			case "0":
				parent.close();
				break;
				
			default:
				break;
			}
		}
	}


	private void cancelDownload() {
		
		if(!parent.downloadingfiles.files.isEmpty()){
			Set<Entry<String, DownloadingFiles.DFile >> set = parent.downloadingfiles.files.entrySet();
			Iterator<Entry<String, DownloadingFiles.DFile>> itr = set.iterator();
			int count = 1;
			System.out.println("Active downloads list: \n");
			while(itr.hasNext()) 
			{
				DownloadingFiles.DFile f = itr.next().getValue();
				f.no = count;
				System.out.println(count + " - " + f.filename + "\n");
				count++;
			}
			System.out.print("0 - Back\n");
			System.out.println("Choose download to cancel: \n");
			BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in));
			String opt = "-1";
			
			while(opt.equals("") || 0 >= Integer.parseInt(opt) || Integer.parseInt(opt) > parent.downloadingfiles.files.size())
			{
				
				try {
					opt = buffer.readLine();
					System.out.print("\n");
				} catch (IOException e1) {
					e1.printStackTrace();
				}
				if(opt.equals("0"))
				{
					//parent.downloadingfiles.files.clear();
					break;
				}
			}
			
			Set<Entry<String, DownloadingFiles.DFile>> set2 = parent.downloadingfiles.files.entrySet();
			Iterator<Entry<String, DownloadingFiles.DFile>> itr2 = set2.iterator();
			
			while(itr2.hasNext()) 
			{
				Entry<String, DownloadingFiles.DFile> choice = itr2.next();
				//String HashValue = choice.getKey();
				DownloadingFiles.DFile f = choice.getValue();
				
				if(f.no == Integer.parseInt(opt)){
					/*parent.startDownload(choice.getKey(),f.size,f.name);
					parent.activesearchid= "";
					files.clear();*/
					parent.downloadingfiles.files.remove(choice.getKey());
					File tmp = new File(choice.getValue().filepath);
					tmp.delete();
					return;
				}
			}
			
		}
		else{
			System.out.println("\nNo active download!\n");
		}
	}

	private void downloadStatus() {
		if(!parent.downloadingfiles.files.isEmpty()){
			Set<Entry<String, DownloadingFiles.DFile>> set = parent.downloadingfiles.files.entrySet();
			Iterator<Entry<String, DownloadingFiles.DFile>> itr = set.iterator();
			int count = 1;
			System.out.println("Active downloads list: \n");
			while(itr.hasNext()) 
			{
				DownloadingFiles.DFile f = itr.next().getValue();
				f.no = count;
				System.out.println(count + " - " + f.filename + " - Recebido: " + (((f.totalchunks-f.remainingchunks.size())*100)/f.totalchunks) +"%\n");
				count++;
			}
			System.out.print("0 - Back\n");
			BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in));
			String opt = "-1";
			while(!opt.equals("0")){
				try {
					opt = buffer.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		else{
			System.out.println("No active download!\n");
		}
	}
	private void getChosenFile() {
		BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in));
		String opt = "-1";
		
		while(opt.equals("") ||0 >= Integer.parseInt(opt) || Integer.parseInt(opt) > files.size())
		{
			
			try {
				opt = buffer.readLine();
				System.out.print("\n");
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			if(opt.equals("0"))
			{
				files.clear();
				break;
			}
		}
		
		Set<Entry<String, FoundFile>> set = files.entrySet();
		Iterator<Entry<String, FoundFile>> itr = set.iterator();
		
		while(itr.hasNext()) 
		{
			Entry<String, FoundFile> choice = itr.next();
			//String HashValue = choice.getKey();
			FoundFile f = choice.getValue();
			
			if(f.no == Integer.parseInt(opt)){
				parent.startDownload(choice.getKey(),f.size,f.name);
				parent.activesearchid= "";
				files.clear();
				return;
			}
		}
		
		
	}

	public void addFoundFile(String sha, String name, int size){
		files.put(sha, new FoundFile(name,size));
	}
	
	private boolean showFiles() {
		
		if(!files.isEmpty()){
			Set<Entry<String, FoundFile>> set = files.entrySet();
			Iterator<Entry<String, FoundFile>> itr = set.iterator();
			int count = 1;
			System.out.println("Founded files list: \n");
			while(itr.hasNext()) 
			{
				FoundFile f = itr.next().getValue();
				f.no = count;
				System.out.println(count + " - " + f.name + "\n");
				count++;
			}
			System.out.print("0 - Back\n");
			System.out.print("\nEscolha o ficheiro a receber: ");
		}
		else{
			System.out.println("No file found!\n");
			return false;
		}
		return true;
	}
}